package com.sephiron.clocksynchronizer;

import java.io.File;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.NavUtils;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class TimeSyncFragment extends Fragment {
    public static final String EXTRA_CCTV_ID = "com.sephiron.clocksynchronizer.cctv_id";
    public static final String EXTRA_EDIT_MODE = "com.sephiron.clocksynchronizer.edit_mode";
    public static final String EXTRA_PICTURE_MODE = "com.sephiron.clocksynchronizer.picture_mode";
    private static final String TAG = "TimeSyncFragmente";
    private static final String DIALOG_DATE = "date";
    private static final String DIALOG_TIME = "time";
    private static final String DIALOG_NAME = "cctv_name";
    private static final String DIALOG_PICTURE_CONFIRM = "choose picture or take one";
    private static final String DIALOG_SET_INTERVAL = "date and time";
    private static final int REQUEST_CCTV_DATE = 0;
    private static final int REQUEST_REAL_DATE = 1;
    private static final int REQUEST_CCTV_TIME = 2;
    private static final int REQUEST_REAL_TIME = 3;
    private static final int REQUEST_CCTV_NAME = 4;
    private static final int REQUEST_SET_REAL_TIME_NOW = 5;
    private static final int REQUEST_SET_TIME_N_DATE_WITH_PICTURE = 6;
    private static final int REQUEST_SELECT_PICTURE = 7;
    private static final int REQUEST_CCTV_N_REAL_TIME_N_DATE = 8;
    private static final int REQUEST_CAPTURE_IMAGE_ACTIVITY = 9;
    private static final int REQUEST_CCTV_DATE_N_TIME = 10;
    private static final int MEDIA_TYPE_IMAGE = 1;
    private static final int MEDIA_TYPE_VIDEO = 2;
    TextView mCctvDecript, mCctvDate, mCctvTime, mRealTime, mRealDate,
            mDifferncy;
    Button mPlusDay, mPlusHour, mPlusMinute, mPlusSecond;
    Button mMinusDay, mMinusHour, mMinusMinute, mMinusSecond;
    Button mSetRealTimeWithPictureTime, mSetRealTimeNow;
    EditText mEditCctvDesc;
    int mCurrentIndex = 0;
    long md;
    boolean editable = false;
    boolean pictureMode = false;
    boolean edited = false;
    SimpleDateFormat dFD;
    SimpleDateFormat dFT = new SimpleDateFormat("HH:mm:ss");
    private Cctv mCctv;
    //TODO: move imageUri into Cctv class
    private Uri imageUri = null;

    public static TimeSyncFragment newInstance(UUID cctvID, Boolean editMode, Boolean pictureMode) {
        Bundle args = new Bundle();
        args.putSerializable(EXTRA_CCTV_ID, cctvID);
        args.putBoolean(EXTRA_EDIT_MODE, editMode);
        args.putBoolean(EXTRA_PICTURE_MODE, pictureMode);

        TimeSyncFragment fragment = new TimeSyncFragment();
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        setRetainInstance(true);

        if (Locale.getDefault().equals(Locale.KOREA) || Locale.getDefault().equals(Locale.KOREAN)) {  dFD = new SimpleDateFormat("yyyy-MM-dd"); } else {dFD = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT);}

        UUID cctvID = (UUID) getArguments().getSerializable(EXTRA_CCTV_ID);
        editable = getArguments().getBoolean(EXTRA_EDIT_MODE, false);
        pictureMode = getArguments().getBoolean(EXTRA_PICTURE_MODE, false);
        if (pictureMode) { getArguments().putBoolean(EXTRA_PICTURE_MODE, false); }

        mCctv = CctvLab.get(getActivity()).getCctv(cctvID);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            try {
                ViewConfiguration config = ViewConfiguration.get(getActivity());
                Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
                if(menuKeyField != null) {
                    menuKeyField.setAccessible(true);
                    menuKeyField.setBoolean(config, false);
                }
            } catch (Exception ex) {
                // Ignore
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_time_sync, parent, false);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            if (NavUtils.getParentActivityName(getActivity()) != null) {
                getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
            }

            getActivity().invalidateOptionsMenu();
        }

        mCctvDate = (TextView) v.findViewById(R.id.CctvDate);
        mCctvTime = (TextView) v.findViewById(R.id.CctvTime);
        mRealDate = (TextView) v.findViewById(R.id.RealDate);
        mRealTime = (TextView) v.findViewById(R.id.RealTime);

        mCctvDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = getActivity().getSupportFragmentManager();

                DatePickerFragment dialog = DatePickerFragment
                        .newInstance(mCctv.getCctvCalendar());
                dialog.setTargetFragment(TimeSyncFragment.this,
                        REQUEST_CCTV_DATE);
                dialog.show(fm, DIALOG_DATE);
            }
        });

        mRealDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = getActivity().getSupportFragmentManager();
                DatePickerFragment dialog = DatePickerFragment
                        .newInstance(mCctv.getRealCalendar());
                dialog.setTargetFragment(TimeSyncFragment.this,
                        REQUEST_REAL_DATE);
                dialog.show(fm, DIALOG_DATE);
            }
        });

        mCctvTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = getActivity().getSupportFragmentManager();
                TimePickerFragment dialog = TimePickerFragment
                        .newInstance(mCctv.getCctvCalendar());
                dialog.setTargetFragment(TimeSyncFragment.this,
                        REQUEST_CCTV_TIME);
                dialog.show(fm, DIALOG_TIME);
            }
        });

        mRealTime.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FragmentManager fm = getActivity().getSupportFragmentManager();
                TimePickerFragment dialog = TimePickerFragment
                        .newInstance(mCctv.getRealCalendar());
                dialog.setTargetFragment(TimeSyncFragment.this,
                        REQUEST_REAL_TIME);
                dialog.show(fm, DIALOG_TIME);
            }
        });

        mDifferncy = (TextView) v.findViewById(R.id.DifferencyDateTime);
        if(editable) {

            mDifferncy.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    FragmentManager fm = getActivity().getSupportFragmentManager();
                    IntervalPickerFragment dialog = IntervalPickerFragment.newInstance(
                            new DateTime(mCctv.getCctvCalendar().getTimeInMillis()),
                            new DateTime(mCctv.getRealCalendar().getTimeInMillis()));
                    dialog.setTargetFragment(TimeSyncFragment.this, REQUEST_CCTV_DATE_N_TIME);
                    dialog.show(fm, DIALOG_SET_INTERVAL);
                }
            });
        }

        updateDifferencyTV();
        updateDateTV();
        updateTimeTV();

        // set realtime now setup
        mSetRealTimeNow = (Button) v.findViewById(R.id.setRealTimeNow);
        mSetRealTimeNow.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                FragmentManager fm = getActivity().getSupportFragmentManager();
                SetRealTimeNowConfirmFragment dialog = SetRealTimeNowConfirmFragment
                        .newInstance();
                dialog.setTargetFragment(TimeSyncFragment.this,
                        REQUEST_SET_REAL_TIME_NOW);
                dialog.show(fm, DIALOG_TIME);
            }
        });

        // plus / minus button setup
        mPlusDay = (Button) v.findViewById(R.id.PlusDay);
        mPlusDay.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.DAY_OF_YEAR, 1);
                mCctv.getRealCalendar().add(Calendar.DAY_OF_YEAR, 1);

                updateDateTV();
                edited = true;
            }
        }));

        mMinusDay = (Button) v.findViewById(R.id.MinusDay);
        mMinusDay.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.DAY_OF_YEAR, -1);
                mCctv.getRealCalendar().add(Calendar.DAY_OF_YEAR, -1);

                updateDateTV();
                edited = true;
            }
        }));

        mPlusHour = (Button) v.findViewById(R.id.PlusHour);
        mPlusHour.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.HOUR_OF_DAY, 1);
                mCctv.getRealCalendar().add(Calendar.HOUR_OF_DAY, 1);

                updateDateTV();
                updateTimeTV();
                edited = true;
            }
        }));

        mMinusHour = (Button) v.findViewById(R.id.MinusHour);
        mMinusHour.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.HOUR_OF_DAY, -1);
                mCctv.getRealCalendar().add(Calendar.HOUR_OF_DAY, -1);

                updateDateTV();
                updateTimeTV();
                edited = true;
            }
        }));

        mPlusMinute = (Button) v.findViewById(R.id.PlusMinute);
        mPlusMinute.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.MINUTE, 1);
                mCctv.getRealCalendar().add(Calendar.MINUTE, 1);

                updateDateTV();
                updateTimeTV();
                edited = true;
            }
        }));

        mMinusMinute = (Button) v.findViewById(R.id.MinusMinute);
        mMinusMinute.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.MINUTE, -1);
                mCctv.getRealCalendar().add(Calendar.MINUTE, -1);

                updateDateTV();
                updateTimeTV();
                edited = true;
            }
        }));

        mPlusSecond = (Button) v.findViewById(R.id.PlusSecond);
        mPlusSecond.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.SECOND, 1);
                mCctv.getRealCalendar().add(Calendar.SECOND, 1);

                updateDateTV();
                updateTimeTV();
                edited = true;
            }
        }));

        mMinusSecond = (Button) v.findViewById(R.id.MinusSecond);
        mMinusSecond.setOnTouchListener(new RepeatListener(500, 150, new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCctv.getCctvCalendar().add(Calendar.SECOND, -1);
                mCctv.getRealCalendar().add(Calendar.SECOND, -1);

                updateDateTV();
                updateTimeTV();
                edited = true;
            }
        }));

        if (editable) {
            getActivity().setTitle(
                    "<" + getResources().getString(R.string.edit_mode) + ">"
                            + getActivity().getTitle());
            mCctvDate.setBackgroundResource(R.drawable.boxshape_small_red);
            mCctvTime.setBackgroundResource(R.drawable.boxshape_small_red);
            mRealDate.setBackgroundResource(R.drawable.boxshape_small_red);
            mRealTime.setBackgroundResource(R.drawable.boxshape_small_red);
            mDifferncy.setBackgroundResource(R.drawable.boxshape_small_red);
        }

        mEditCctvDesc = (EditText) v.findViewById(R.id.fragment_time_sync_edit_cctv_desc);
        mEditCctvDesc.setText(mCctv.getCctvDesc());
        mEditCctvDesc.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mEditCctvDesc.setFocusableInTouchMode(true);
                mEditCctvDesc.setCursorVisible(true);
                return false;
            }
        });
        mEditCctvDesc.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // TODO Auto-generated method stub
                edited = true;
                mCctv.setCctvDesc(s.toString());
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub

            }
        });
        return v;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (pictureMode) {
            pictureMode = false;
            FragmentManager fm2 = getActivity().getSupportFragmentManager();

            SetTimeNDateWithPictureConfirmFragment dialog2 = SetTimeNDateWithPictureConfirmFragment.newInstance();
            dialog2.setTargetFragment(TimeSyncFragment.this, REQUEST_SET_TIME_N_DATE_WITH_PICTURE);
            dialog2.show(fm2, DIALOG_PICTURE_CONFIRM);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK && resultCode != Activity.RESULT_FIRST_USER )
            return;

        edited = true;

        Calendar resultCal;
        DateTime resultDt; // DATETIME version val of resultCal
        DateTime dtMCC = new DateTime(mCctv.getCctvCalendar().getTimeInMillis());
        DateTime dtMCR = new DateTime(mCctv.getRealCalendar().getTimeInMillis());
        DateTime dtResultCal;
        Interval intv;

        switch (requestCode) {

            case REQUEST_CCTV_DATE:

                resultCal = (Calendar) data
                        .getSerializableExtra(DatePickerFragment.EXTRA_DATE);

                dtResultCal = new DateTime(resultCal.getTimeInMillis());

                if (!editable) {
                    if (dtResultCal.isAfter(dtMCC)) {
                        // 새값이 나중일 때(커졌을 떄)
                        intv = new Interval(dtMCC, dtResultCal);
                        dtMCR = dtMCR.plus(intv.toDuration());

                        mCctv.getCctvCalendar().setTime(dtResultCal.toDate());
                        mCctv.getRealCalendar().setTime(dtMCR.toDate());
                    } else {
                        // 새값이 이전일 때(작아졌을 떄)
                        intv = new Interval(dtResultCal, dtMCC);
                        dtMCR = dtMCR.minus(intv.toDuration());

                        mCctv.getCctvCalendar().setTime(dtResultCal.toDate());
                        mCctv.getRealCalendar().setTime(dtMCR.toDate());
                    }
                } else {
                    mCctv.setCctvCalendar(resultCal);
                    updateDifferencyTV();
                }
                updateDateTV();
                break;

            case REQUEST_REAL_DATE:

                resultCal = (Calendar) data
                        .getSerializableExtra(DatePickerFragment.EXTRA_DATE);

                dtResultCal = new DateTime(resultCal.getTimeInMillis());

                if (!editable) {
                    if (dtResultCal.isAfter(dtMCR)) {
                        // 새값이 나중일 때(커졌을 떄)
                        intv = new Interval(dtMCR, dtResultCal);
                        dtMCC = dtMCC.plus(intv.toDuration());

                        mCctv.getRealCalendar().setTime(dtResultCal.toDate());
                        mCctv.getCctvCalendar().setTime(dtMCC.toDate());
                    } else {
                        // 새값이 이전일 때(작아졌을 떄)
                        intv = new Interval(dtResultCal, dtMCR);
                        dtMCC = dtMCC.minus(intv.toDuration());

                        mCctv.getRealCalendar().setTime(dtResultCal.toDate());
                        mCctv.getCctvCalendar().setTime(dtMCC.toDate());
                    }
                } else {
                    mCctv.setRealCalendar(resultCal);
                    updateDifferencyTV();
                }
                updateDateTV();
                break;

            case REQUEST_CCTV_TIME:

                resultCal = (Calendar) data
                        .getSerializableExtra(TimePickerFragment.EXTRA_TIME);

                dtResultCal = new DateTime(resultCal.getTimeInMillis());

                if (!editable) {
                    if (dtResultCal.isAfter(dtMCC)) {
                        // 새값이 나중일 때(커졌을 떄)
                        intv = new Interval(dtMCC, dtResultCal);
                        dtMCR = dtMCR.plus(intv.toDuration());

                        mCctv.getCctvCalendar().setTime(dtResultCal.toDate());
                        mCctv.getRealCalendar().setTime(dtMCR.toDate());
                    } else {
                        // 새값이 이전일 때(작아졌을 떄)
                        intv = new Interval(dtResultCal, dtMCC);
                        dtMCR = dtMCR.minus(intv.toDuration());

                        mCctv.getCctvCalendar().setTime(dtResultCal.toDate());
                        mCctv.getRealCalendar().setTime(dtMCR.toDate());
                    }
                } else {
                    mCctv.setCctvCalendar(resultCal);
                    updateDifferencyTV();
                }
                updateDateTV();
                updateTimeTV();
                break;

            case REQUEST_REAL_TIME:

                resultCal = (Calendar) data
                        .getSerializableExtra(TimePickerFragment.EXTRA_TIME);

                dtResultCal = new DateTime(resultCal.getTimeInMillis());

                if (!editable) {
                    if (dtResultCal.isAfter(dtMCR)) {
                        // 새값이 나중일 때(커졌을 떄)
                        intv = new Interval(dtMCR, dtResultCal);
                        dtMCC = dtMCC.plus(intv.toDuration());

                        mCctv.getRealCalendar().setTime(dtResultCal.toDate());
                        mCctv.getCctvCalendar().setTime(dtMCC.toDate());
                    } else {
                        // 새값이 이전일 때(작아졌을 떄)
                        intv = new Interval(dtResultCal, dtMCR);
                        dtMCC = dtMCC.minus(intv.toDuration());

                        mCctv.getRealCalendar().setTime(dtResultCal.toDate());
                        mCctv.getCctvCalendar().setTime(dtMCC.toDate());
                    }
                } else {
                    mCctv.setRealCalendar(resultCal);
                    updateDifferencyTV();
                }
                updateDateTV();
                updateTimeTV();
                break;

            case REQUEST_CCTV_NAME:
                mCctv.setCctvName(data
                        .getStringExtra(NameEditorFragment.EXTRA_NAME));
                getActivity().setTitle(mCctv.getCctvName());
                if (editable) {
                    getActivity().setTitle(
                            "<" + getResources().getString(R.string.edit_mode)
                                    + ">" + getActivity().getTitle());
                }
                break;

            case REQUEST_SET_REAL_TIME_NOW:
                resultCal = (Calendar) data
                        .getSerializableExtra(SetRealTimeNowConfirmFragment.EXTRA_PRESENT_TIME);
                dtResultCal = new DateTime(resultCal.getTimeInMillis());

                if (!editable) {
                    if (dtResultCal.isAfter(dtMCR)) {
                        // 새값이 나중일 때(커졌을 떄)
                        intv = new Interval(dtMCR, dtResultCal);
                        dtMCC = dtMCC.plus(intv.toDuration());

                        mCctv.getRealCalendar().setTime(dtResultCal.toDate());
                        mCctv.getCctvCalendar().setTime(dtMCC.toDate());
                    } else {
                        // 새값이 이전일 때(작아졌을 떄)
                        intv = new Interval(dtResultCal, dtMCR);
                        dtMCC = dtMCC.minus(intv.toDuration());

                        mCctv.getRealCalendar().setTime(dtResultCal.toDate());
                        mCctv.getCctvCalendar().setTime(dtMCC.toDate());
                    }
                } else {
                    mCctv.setRealCalendar(resultCal);
                    updateDifferencyTV();
                }
                updateDateTV();
                updateTimeTV();
                break;

            case REQUEST_SET_TIME_N_DATE_WITH_PICTURE:
                // 새 사진으로
                if (resultCode == Activity.RESULT_OK) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    imageUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                    startActivityForResult(intent, REQUEST_CAPTURE_IMAGE_ACTIVITY);

                    //기존 사진으로
                } else {
                    // Pick a Picture
                    Intent intent = new Intent(Intent.ACTION_PICK);
                    intent.setType("image/*");
                    startActivityForResult(intent, REQUEST_SELECT_PICTURE);
                }
                break;

            case REQUEST_SELECT_PICTURE:
                if (resultCode == Activity.RESULT_OK) {
                    if (!editable) {
                        break;
                    } else {
                        Intent i = new Intent();
                        i.setData(data.getData());
                        i.putExtra(SetDateNTimeWithPictureFragment.EXTRA_CCTV_CALENDAR, mCctv.getCctvCalendar());
                        i.putExtra(SetDateNTimeWithPictureFragment.EXTRA_PICTURE_PATH, getRealPathFromURI(getActivity(), data.getData()));
                        i.setClass(getActivity(), SetDateNTimeWithPictureActivity.class);
                        startActivityForResult(i, REQUEST_CCTV_N_REAL_TIME_N_DATE);
                    }
                }
                break;


            case REQUEST_CAPTURE_IMAGE_ACTIVITY:
                if (resultCode == Activity.RESULT_OK) {
                    if (!editable) {
                        break;
                    } else if (imageUri != null) {
                        Intent i = new Intent();
                        i.setData(imageUri);
                        i.putExtra(SetDateNTimeWithPictureFragment.EXTRA_CCTV_CALENDAR, mCctv.getCctvCalendar());
                        i.putExtra(SetDateNTimeWithPictureFragment.EXTRA_PICTURE_PATH, imageUri.getPath());
                        i.setClass(getActivity(), SetDateNTimeWithPictureActivity.class);
                        startActivityForResult(i, REQUEST_CCTV_N_REAL_TIME_N_DATE);
                    } else {
                        Log.d(TAG, getResources().getString(R.string.error_on_capturing_image));
                    }
                }
                break;

            case REQUEST_CCTV_N_REAL_TIME_N_DATE:
                if (resultCode == Activity.RESULT_OK) {
                    if (!editable) {
                        break;
                    } else {
                        Calendar resultCalCCTV = (Calendar) data.getSerializableExtra(SetDateNTimeWithPictureFragment.EXTRA_CCTV_CALENDAR);
                        Calendar resultCalREAL = (Calendar) data.getSerializableExtra(SetDateNTimeWithPictureFragment.EXTRA_REAL_CALENDAR);
                        mCctv.setCctvCalendar(resultCalCCTV);
                        mCctv.setRealCalendar(resultCalREAL);

                        updateDateTV();
                        updateTimeTV();
                        updateDifferencyTV();
                    }
                }
                break;

            case REQUEST_CCTV_DATE_N_TIME:
                if (resultCode == Activity.RESULT_OK) {
                    if (!editable) {
                        break;
                    } else {
                        resultDt = (DateTime) data.getSerializableExtra(IntervalPickerFragment.EXTRA_DATETIME_CCTV);
                        mCctv.setCctvCalendar(resultDt.toCalendar(Locale.getDefault()));

                        updateDateTV();
                        updateTimeTV();
                        updateDifferencyTV();
                    }
                }
        }
    }


    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.fragment_time_sync, menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                if (NavUtils.getParentActivityName(getActivity()) != null) {
                    NavUtils.navigateUpFromSameTask(getActivity());
                }
                return true;

            case R.id.menu_item_edit_mode: // 수정모드 또는 수정완료 메뉴
                if (editable) { // 수정완료
                    Intent i = new Intent(getActivity(),
                            TimeSyncPagerActivity.class);
                    i.putExtra(EXTRA_CCTV_ID,
                            getArguments().getSerializable(EXTRA_CCTV_ID));
                    i.putExtra(EXTRA_EDIT_MODE, false);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                            | Intent.FLAG_ACTIVITY_NEW_TASK
                            | Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    getActivity().overridePendingTransition(0, 0);
                    getActivity().finish();

                    // getActivity().overridePendingTransition(0, 0);
                    startActivity(i);
                } else { // 수정모드 진입
                    Intent i = new Intent(getActivity(),
                            TimeSyncEditModeActivity.class);
                    i.putExtra(EXTRA_CCTV_ID,
                            getArguments().getSerializable(EXTRA_CCTV_ID));
                    i.putExtra(EXTRA_EDIT_MODE, true);
                    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                            | Intent.FLAG_ACTIVITY_NEW_TASK
                            | Intent.FLAG_ACTIVITY_NO_ANIMATION);
                    getActivity().overridePendingTransition(0, 0);
                    getActivity().finish();

                    // getActivity().overridePendingTransition(0, 0);
                    startActivity(i);
                }
                return true;

            case R.id.menu_item_edit_desc_name:
                FragmentManager fm = getActivity().getSupportFragmentManager();

                NameEditorFragment dialog = NameEditorFragment.newInstance(mCctv
                        .getCctvName());
                dialog.setTargetFragment(TimeSyncFragment.this, REQUEST_CCTV_NAME);
                dialog.show(fm, DIALOG_NAME);

                return true;

            // TODO : set desc editfield editable later

            case R.id.menu_item_picture:
                FragmentManager fm2 = getActivity().getSupportFragmentManager();

                SetTimeNDateWithPictureConfirmFragment dialog2 = SetTimeNDateWithPictureConfirmFragment.newInstance();
                dialog2.setTargetFragment(TimeSyncFragment.this, REQUEST_SET_TIME_N_DATE_WITH_PICTURE);
                dialog2.show(fm2, DIALOG_PICTURE_CONFIRM);

                return true;

            case R.id.menu_item_help_time_sync:
                if (editable) {
                    Intent i = new Intent(getActivity(), HelpActivity.class);
                    i.putExtra(HelpActivity.EXTRA_HELP_MODE,
                            HelpActivity.TIME_SYNC_EDIT_MODE_HELP);
                    startActivity(i);
                } else {
                    Intent i = new Intent(getActivity(), HelpActivity.class);
                    i.putExtra(HelpActivity.EXTRA_HELP_MODE,
                            HelpActivity.TIME_SYNC_HELP);
                    startActivity(i);
                }
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);

        if (editable) {
            menu.findItem(R.id.menu_item_edit_mode).setTitle(
                    R.string.edit_complete);
            menu.findItem(R.id.menu_item_edit_mode).setIcon(
                    R.drawable.ic_cab_done_holo_light);
            menu.findItem(R.id.menu_item_picture).setVisible(true);
        }
    }

    @Override
    public void onPause() {
        super.onPause();

        if (edited) {
            CctvLab.get(getActivity()).saveCctvs();
            edited = false;
        }
    }

    private void updateDateTV() {
        mCctvDate.setText(dFD.format(mCctv.getCctvCalendar().getTime()));
        mRealDate.setText(dFD.format(mCctv.getRealCalendar().getTime()));

    }

    private void updateTimeTV() {
        mCctvTime.setText(dFT.format(mCctv.getCctvCalendar().getTime()));
        mRealTime.setText(dFT.format(mCctv.getRealCalendar().getTime()));
    }

    private void updateDifferencyTV() {
        mCctv.getCctvCalendar().set(Calendar.MILLISECOND, 0);
        mCctv.getRealCalendar().set(Calendar.MILLISECOND, 0);
        Period p = new Period(new DateTime(mCctv.getCctvCalendar()),
                new DateTime(mCctv.getRealCalendar()));
        Days days = Days.daysBetween(new DateTime(mCctv.getCctvCalendar()),
                new DateTime(mCctv.getRealCalendar()));

        PeriodFormatter pf = new PeriodFormatterBuilder().appendHours()
                .appendSuffix(getResources().getString(R.string.hour)).appendSeparator(" ").appendMinutes()
                .appendSuffix(getResources().getString(R.string.minute)).appendSeparator(" ").appendSeconds()
                .appendSuffix(getResources().getString(R.string.second)).toFormatter();

//        mDifferncy.setText("CCTV가 " + String.valueOf(days.getDays()) + "일 "
//                + pf.print(p.normalizedStandard()) + " 느림\n(-면 빠름)");
        mDifferncy.setText(String.format(getResources().getString(R.string.fragment_time_sync_interval), days.getDays(), pf.print(p.normalizedStandard())));
    }

    /** Create a file Uri for saving an image or video */
    private Uri getOutputMediaFileUri(int type){
        return Uri.fromFile(getOutputMediaFile(type));
    }

    /** Create a File for saving an image or video */
    private File getOutputMediaFile(int type){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), getString(R.string.app_name));
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d(getString(R.string.app_name), "failed to create directory");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE){
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "IMG_"+mCctv.getCctvName()+"_"+ timeStamp + ".jpg");
        } else if(type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                    "VID_"+ timeStamp + ".mp4");
        } else {
            return null;
        }

        return mediaFile;
    }

    public Uri convertContentUriToRealPathUri(Uri contentUri) {
        return Uri.parse(getRealPathFromURI(getActivity(), contentUri));
    }

    public String getRealPathFromURI(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri,  proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
}
